package cn.xyfmzmy.chain.validation;

import cn.xyfmzmy.chain.exception.ValidationException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 校验链的上下文
 *
 * 责任链模式的核心思想：
 * 1. 责任链中的每一个节点都可以对主流程进行干预，如通过doNext方法控制是否继续执行，改变传递的参数(这里是value)
 * 2. 主流程可以汇聚所有节点的执行结果，如这里的data这个map可以记录执行过程中的一些信息
 */
public class ValidateContext {

    // 存储各个节点的异常信息
    private List<String> errorMessageList = new ArrayList<>();

    // 用于控制是否在某个节点停止
    private boolean stop = false;

    // 记录当前节点的下标
    private int index = 0;

    // 责任链执行过程中要传递的信息
    private Object value;

    // 在责任链的执行过程中记录一些信息
    private Map<String,Object> data = new HashMap<>();

    public ValidateContext(Object value) {
        this.value = value;
    }

    // 只有节点执行了doNext方法，责任链才往下走，如netty里的pipeline，servelet的filter
    // 让节点能够自行控制是否往下走，并且能够修改传递的信息
    public void doNext(Object value){
        index++;
        this.value = value;
    }

    // 获取当前节点下标
    public int currentIndex(){
        return this.index;
    }

    public void set(String key,Object value){
        this.data.put(key,value);
    }

    public Object get(String key){
        return this.data.get(key);
    }


    public void appendError(String errorMessage){
        errorMessageList.add(errorMessage);
    }

    public void throwExceptionIfNessary() throws ValidationException{
        if(errorMessageList.isEmpty()){
            return;
        }
        throw new ValidationException(errorMessageList.toString());
    }



    // 让节点可以通过stopChain方法停止责任链，这里没加相应的判断逻辑，用doNext来进行控制
    public void stopChain(){
        this.stop = true;
    }

    public boolean shouldStop(){
        return this.stop;
    }

}
